using System;
using System.Collections.Generic;
using System.Text;

namespace PastCrew.Games.Chess.Engine.Entities.Pieces
{
    public sealed class Pawn : BasePiece
    {       

        #region constructors

        /// <summary>
        /// 
        /// </summary>
        public Pawn()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pieceColor"></param>
        public Pawn(Color pieceColor)
        {
            base.Color = pieceColor;
        }

        #endregion

        #region public methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public sealed override List<Entities.SquareStatus> GetValidMoves()
        {
            #region set up color dependant properties

            int startPosition;
            int promotePosition;
            int pawnMoveFwd;

            if (this.Color == Color.white)
            {
                startPosition = 1;
                promotePosition = 7;
                pawnMoveFwd = 1;
            }
            else
            {
                startPosition = 6;
                promotePosition = 0;
                pawnMoveFwd = -1;
            }

            #endregion

            #region pawn rule set

            Board.Position currentPosition = this.CurrentSquare.Position;
            List<Entities.SquareStatus> validPositions = new List<Entities.SquareStatus>();

            // Check if the pawn begins from start position --> 2 positions forward / 'en passant'
            if (startPosition == currentPosition.Y && false == this.HasMoved)
            {
                Board.Square squareOneNorth = Board.GetSquare(currentPosition.X, (currentPosition.Y + pawnMoveFwd));               // Pawn moves single step forward
                Board.Square squareTwoNorth = Board.GetSquare(currentPosition.X, (currentPosition.Y + pawnMoveFwd + pawnMoveFwd)); // Pawn moves double step forward

                if (!squareOneNorth.Occupied && !squareTwoNorth.Occupied)
                {
                    // The pawn can move two steps forward
                    Entities.SquareStatus squareStat = new SquareStatus(squareTwoNorth, MoveResult.valid & MoveResult.enpassant);
                    validPositions.Add(squareStat);
                }
            }

            // Ensure that for both white and black pawns, the same logic can be used. The 'end-of-board' reached number can be the same for both white and black
            int referencePosition = this.Color == Color.white ? (promotePosition - pawnMoveFwd) : 7 - (promotePosition - pawnMoveFwd);
            // If the end of the board has not been reached, you can move one forward
            if (currentPosition.Y <= referencePosition) // Leaves one square open in front of the pawn
            {
                // Check straight ahead one step
                Board.Square squareForward = Board.GetSquare(currentPosition.X, (currentPosition.Y + pawnMoveFwd));
                if (!squareForward.Occupied)
                {
                    MoveResult result;
                    if (squareForward.Position.Y == promotePosition)
                        result = MoveResult.valid & MoveResult.promotion;
                    else
                        result = MoveResult.valid;

                    Entities.SquareStatus squareStat = new SquareStatus(squareForward, result);
                    validPositions.Add(squareStat);
                }

                // Check for diagonal forward moves
                if (currentPosition.X >= 1) // Must have at least one square open to move left
                {
                    Board.Square squareDiagonalLeft = Board.GetSquare((currentPosition.X - 1), currentPosition.Y + pawnMoveFwd);   // Pawn moves diagonal left forward
                    if (squareDiagonalLeft.Occupied && squareDiagonalLeft.Occupant.Color != this.Color)
                    {
                        // The pawn can move diagonally left when taking a piece of the opponent
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalLeft, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
                if (currentPosition.X <= 6) // Must have at least one square open to move right
                {
                    Board.Square squareDiagonalRight = Board.GetSquare((currentPosition.X + 1), currentPosition.Y + pawnMoveFwd);  // Pawn moves diagonal left forward
                    if (squareDiagonalRight.Occupied && squareDiagonalRight.Occupant.Color != this.Color)
                    {
                        // The pawn can move diagonally right when taking a piece of the opponent
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalRight, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
            }
            

            #endregion

            return validPositions;
        }

        #endregion
    }
}
